const addTwoNumbers = (l1, l2) => {
  const l3 = new ListNode(0)
  let p1 = l1;
  let p2 = l2;
  let p3 = l3;
  /*
    carry
    美: [ˈkeri] 英: [ˈkæri]
    v.	携带；搬；拿；提
    n.	携带；〈美〉运输；空；(两条水道间)陆上运送
    网络	搬运；进位；运载

    取 进位 的意思
  */
  let carry = 0;
  while(p1 || p2) { //l1、l2都遍历完了才是真完了
    const v1 = p1 ? p1.val : 0;
    const v2 = p2 ? p2.val : 0;
    const val = v1 + v2 + carry;
    //进位 下一轮要叠加的值
    carry = Math.floor(val / 10);   // 9+9 -> 18 -> Math.floor(18/10) -> 1 //emmm 进位也只可能为1 小于10就没有进位 大于10就进位1 // 每次迭代都有这一步 所以不用担心过期
    p3.next = new ListNode(val % 10);
    if(p1) p1 = p1.next;
    if(p2) p2 = p2.next;
    p3 = p3.next;
  }
  if(carry) p3.next = new ListNode(carry);
  return l3.next;
};

//时间复杂: 有一个while循环体 时间复杂度为O(n) n为l1和l2链表的较长值
//空间复杂度: 空间复杂度也为O(n),即线性增长（while里有p3.next = new ListNode(val % 10)）, n是l1和l2链表中较大的那个

// 更人类的写法 ↓
var addTwoNumbers = function(l1, l2) {
  let l3 = new ListNode(0);
  let p1 = l1,
    p2 = l2,
    p3 = l3,
    carry = 0;

  while(p1||p2){
    const v1 = p1? p1.val : 0;
    const v2 = p2? p2.val : 0;
    const val = v1 + v2 + carry;
    p3.val = val%10;
    carry = Math.floor(val/10);
    if(p1) p1 = p1.next;
    if(p2) p2 = p2.next;
    if(p1||p2) p3 = p3.next = new ListNode(0);
  }
  if(carry)p3.next = new ListNode(carry);

  return l3;
};
